home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Networking / ATP Demo 1.0 / ATP.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-28  |  24.0 KB  |  981 lines  |  [TEXT/MPS ]

  1. /*****************************************************************
  2.  
  3.     Program:    < ATP Demo >
  4.     File:        < ATP.c >
  5.     
  6.     Written by  Scott Kuechle
  7.     of <Apple Macintosh Developer Technical Support>
  8.     
  9.     10/92 SRK created
  10.     8/94 SRK Modified to use a queue of parameter
  11.              blocks.
  12.  
  13.     Copyright © 1992, 1994 Apple Computer, Inc.
  14.     All rights reserved.
  15.     
  16. *****************************************************************/
  17.  
  18. /*****************************************************************/
  19. /*  I N C L U D E S
  20. /*****************************************************************/
  21.  
  22. #include    "ATP Demo.h"
  23. #include    "ATP Demo.protos"
  24.  
  25. /********************************************************************
  26. /*  G L O B A L   V A R I A B L E   D E C L A R A T I O N S
  27. /********************************************************************/
  28.  
  29.  
  30. char                 gOurATPSocket;
  31. Str255                 gDataSizeStr;
  32. Boolean             gDoContinuous;
  33. AddrBlock             gTargetAddress;
  34.  
  35. myATPParamBlock     gOurPB[maxQElements];
  36. ourRespBuf            gRespBuf[maxQElements];
  37. BDSType                gBDS[maxQElements];
  38. ourReqData            gOurReqData[maxQElements];
  39.  
  40. QHdr                gAvailQueue;
  41. QHdr                gDoneQueue;
  42. QHdr                gRequestQueue;
  43.  
  44.  
  45. /*****************************************************************/
  46. /*
  47. /* E X T E R N A L S
  48. /*
  49. /*****************************************************************/
  50.  
  51. extern void     ShowError(short index);
  52. extern void     Exit(short message);
  53. extern Str255     gZoneString, gObjStr, gTypeStr;
  54. extern void     registerMyName(char socket);
  55. extern DialogPtr myDialog;
  56. extern void     removeMyName();
  57. extern void     FatalError(error);
  58. extern void     HiliteSendReqButton (short mode);
  59. extern void     PreCompletion();
  60. extern Boolean    gReqClockTime,gSingleRequest,gStopRequests;
  61. extern Handle     gTestDataHdl;
  62. extern long     gTestDataSize;
  63.  
  64.  
  65.  
  66.  
  67. #pragma segment atp
  68. // *****************************************************************
  69. // *    GetASocket
  70. // *
  71. // *    Opens a socket for us to receive requests - we will accept
  72. // *    requests from any machine.
  73. // *
  74. // *****************************************************************
  75. Boolean GetASocket(char *socket)
  76. {
  77. ATPParamBlock atp;
  78.  
  79.     *socket = 0;
  80.     
  81.     atp.ATP.ioCompletion = nil;
  82.         /* dynamically allocate us a socket */
  83.     atp.ATP.atpSocket = 0;
  84.     
  85.         /* accept requests from anyone */
  86.     atp.ATP.addrBlock.aNet = 0;
  87.     atp.ATP.addrBlock.aNode = 0;
  88.     atp.ATP.addrBlock.aSocket = 0;
  89.     
  90.     if (POpenATPSkt(&atp,false) == noErr)
  91.     {
  92.         if (atp.ATP.ioResult == noErr)
  93.         {
  94.             *socket = atp.ATP.atpSocket;
  95.             return true;
  96.         }
  97.     }
  98.     
  99.     return false;
  100. }
  101.  
  102. // *****************************************************************
  103. // *    InitQueues
  104. // *
  105. // *    initialize our "Available" , "Done" and "Read" queues
  106. // *****************************************************************
  107.  
  108. void InitQueues()
  109. {
  110. short i;
  111. long myA5;
  112.  
  113.     gAvailQueue.qHead     = NULL;
  114.     gAvailQueue.qTail     = NULL;
  115.  
  116.     gDoneQueue.qHead     = NULL;
  117.     gDoneQueue.qTail     = NULL;
  118.  
  119.     gRequestQueue.qHead = NULL;
  120.     gRequestQueue.qTail = NULL;
  121.     
  122.     myA5 = *(long *)CurrentA5;
  123.     
  124.     for (i=0; (i < maxQElements); ++i)
  125.     {
  126.         gOurPB[i].reqData                 = (Ptr)&gOurReqData[i];
  127.         gOurPB[i].respData                 = (Ptr)&gRespBuf[i];
  128.         gOurPB[i].bdsPtr                 = (Ptr)&gBDS[i];
  129.         gOurPB[i].myA5                     = myA5;
  130.         gOurPB[i].u.ATP.ioCompletion     = (ProcPtr)&PreCompletion;
  131.  
  132.         Enqueue((QElemPtr)&gOurPB[i].u,&gAvailQueue);
  133.     }
  134.  
  135. }
  136.  
  137.  
  138. // *****************************************************************
  139. // *    GetQElement
  140. // *
  141. // *    retrieve a queue element from the specified queue
  142. // *****************************************************************
  143.  
  144. ATPPBPtr GetQElement(QHdrPtr qHdrPtr)
  145. {
  146. OSErr err;
  147. QElemPtr qElemPtr;
  148.  
  149.     CheckDoneQueue();
  150.  
  151.     qElemPtr = qHdrPtr->qHead;
  152.     if (qElemPtr != NULL)
  153.     {
  154.         err = Dequeue((QElemPtr)qElemPtr,qHdrPtr);
  155.         if (err != noErr)
  156.         {
  157.             return NULL;
  158.         }
  159.         else
  160.         {
  161.             return (ATPPBPtr)(qElemPtr);
  162.         }
  163.     }
  164.     else
  165.         return NULL;
  166. }
  167.  
  168. // *****************************************************************
  169. // *    GetOurPBPtr
  170. // *
  171. // *    Returns a pointer to our custom parameter block
  172. // *****************************************************************
  173.  
  174. myATPParamBlockPtr GetOurPBPtr(ATPPBPtr atpPBPtr)
  175. {
  176. Ptr p;
  177. myATPParamBlockPtr myATPPBPtr;
  178.  
  179.     p = (Ptr)atpPBPtr;
  180.         /* set a pointer to our parameter block,
  181.             which is offset kOurPBNegOffset bytes
  182.             above the standard ATP param block */
  183.     myATPPBPtr = (myATPParamBlockPtr)(p - kOurPBNegOffset);
  184.     
  185.     return (myATPPBPtr);
  186.     
  187. }
  188.  
  189.  
  190. // *****************************************************************
  191. // *    SetOurCompletionRoutine
  192. // *
  193. // *    Sets the "real" completion routine for our async. calls
  194. // *****************************************************************
  195. void SetOurCompletionRoutine(ProcPtr procPtr,
  196.                             ATPPBPtr atpPBPtr)
  197. {
  198. myATPParamBlockPtr myATPPBPtr;
  199.  
  200.     myATPPBPtr = GetOurPBPtr(atpPBPtr);
  201.     myATPPBPtr->ourCompletion = procPtr;
  202.     
  203. }
  204.  
  205. // *****************************************************************
  206. // *    SaveFunctionResultCode
  207. // *
  208. // *    Places the function result code in our pb structure for later
  209. // *    reporting.
  210. // *****************************************************************
  211. void SaveFunctionResultCode(OSErr err,
  212.                             ATPPBPtr atpPBPtr)
  213. {
  214. myATPParamBlockPtr myATPPBPtr;
  215.  
  216.     myATPPBPtr = GetOurPBPtr(atpPBPtr);
  217.         /* save off the function result */
  218.     myATPPBPtr->functionResult = err;
  219.         /* place pb in "done" queue so we
  220.             can report the error later */
  221.     Enqueue((QElemPtr)atpPBPtr,&gDoneQueue);
  222.  
  223. }
  224.  
  225. // *****************************************************************
  226. // *    doGetRequestIOComp
  227. // *
  228. // *    Completion routine for our get request call. We get here if
  229. // *    another machine sends us a request with the send request call.
  230. // *****************************************************************
  231. pascal void doGetRequestIOComp(ATPPBPtr atpPBPtr)
  232. {
  233.     if (atpPBPtr->ATP.ioResult == noErr)
  234.             /* place parameter block into the "Request" queue */
  235.         Enqueue((QElemPtr)atpPBPtr,&gRequestQueue);
  236.     else    /* some kind of error was returned */
  237.             /* place parameter block back into the "Done" queue */
  238.         Enqueue((QElemPtr)atpPBPtr,&gDoneQueue);
  239. }
  240.  
  241. // *****************************************************************
  242. // *    doGetRequest
  243. // *
  244. // *    We issue an asynchronous get request call here. It will complete
  245. // *    if a request is received from another machine.
  246. // *****************************************************************
  247. void doGetRequest(ATPPBPtr atpPBPtr,
  248.                     char socket,
  249.                     short reqLength,
  250.                     Ptr reqPointer)
  251. {
  252. OSErr err;
  253.  
  254.     SetOurCompletionRoutine((ProcPtr)&doGetRequestIOComp,
  255.                             atpPBPtr);
  256.     atpPBPtr->ATP.atpSocket     = socket;
  257.     atpPBPtr->ATP.reqLength     = reqLength;
  258.     atpPBPtr->ATP.reqPointer     = reqPointer;
  259.  
  260.     err = PGetRequest(atpPBPtr,true);
  261.     if (err != noErr)
  262.     {
  263.         SaveFunctionResultCode(err,
  264.                             atpPBPtr);
  265.     }
  266.     
  267. }
  268.  
  269. // *****************************************************************
  270. // *    doSndRequestIOComp
  271. // *
  272. // *    This is the completion routine for our send request call. It
  273. // *    will get called as soon as a response is received from the target.
  274. // *****************************************************************
  275. pascal void doSndRequestIOComp(ATPPBPtr atpPBPtr)
  276. {
  277.     if (atpPBPtr->ATP.ioResult == noErr)
  278.     {
  279.             /* place parameter block into the "Request" queue */
  280.         Enqueue((QElemPtr)atpPBPtr,&gRequestQueue);
  281.     }
  282.     else    /* we got an error */
  283.     {        /* place parameter block into the "Done" queue */
  284.         Enqueue((QElemPtr)atpPBPtr,&gDoneQueue);
  285.     }
  286.     
  287. }
  288.  
  289. // *****************************************************************
  290. // *    doSndRequest
  291. // *
  292. // *    This is our send request call. We send a request to the target,
  293. // *    as specified in the popup menu. The call completes when a 
  294. // *    response is received back.
  295. // *****************************************************************
  296. void doSndRequest(ATPPBPtr         atpPBPtr,
  297.                     AddrBlock     address,
  298.                     char        socket,
  299.                     Ptr         bdsPtr,
  300.                     short         reqLength,
  301.                     Ptr         reqPointer,
  302.                     char         numOfBuffs)
  303. {
  304. OSErr err;
  305.  
  306.     SetOurCompletionRoutine((ProcPtr)&doSndRequestIOComp,
  307.                             atpPBPtr);
  308.     atpPBPtr->SREQ.atpSocket         = socket;
  309.     
  310.     atpPBPtr->SREQ.addrBlock.aNet     = address.aNet;
  311.     atpPBPtr->SREQ.addrBlock.aNode     = address.aNode;
  312.     atpPBPtr->SREQ.addrBlock.aSocket = address.aSocket;
  313.     
  314.     atpPBPtr->SREQ.reqLength         = reqLength;
  315.     atpPBPtr->SREQ.reqPointer         = reqPointer;
  316.     
  317.     atpPBPtr->SREQ.bdsPointer         = bdsPtr;
  318.  
  319.     atpPBPtr->SREQ.atpFlags         = atpEOMvalue + atpSendChkvalue;    
  320.     atpPBPtr->SREQ.timeOutVal         = kATPTimeOutVal;
  321.     atpPBPtr->SREQ.retryCount         = kATPRetryCount;
  322.         /* number of response datagrams that will be accepted */
  323.     atpPBPtr->SREQ.filler             = numOfBuffs;
  324.  
  325.     err = PNSendRequest(atpPBPtr,true);
  326.     if (err != noErr)
  327.     {
  328.         SaveFunctionResultCode(err,
  329.                             atpPBPtr);
  330.     }
  331.     
  332. }
  333.  
  334.  
  335.  
  336. // *****************************************************************
  337. // *    SendOurResponseData
  338. // *
  339. // *****************************************************************
  340. void SendOurResponseData(ATPPBPtr atpPBPtr)
  341. {
  342. char reqCode;
  343. BDSPtr bdsPtr;
  344. myATPParamBlockPtr myATPBPtr;
  345. short nElements;
  346.  
  347.         reqCode = *(atpPBPtr->ATP.reqPointer);
  348.         switch( reqCode )
  349.         {
  350.             case kSendTime:
  351.                     myATPBPtr = GetOurPBPtr(atpPBPtr);
  352.                     bdsPtr = (BDSPtr)myATPBPtr->bdsPtr;
  353.                     GetClockTime(myATPBPtr->respData);
  354.                     nElements = BuildBDS(myATPBPtr->respData,
  355.                                         myATPBPtr->bdsPtr,
  356.                                         4);
  357.                     doSendResponse(atpPBPtr,
  358.                                     gOurATPSocket,
  359.                                     (Ptr)bdsPtr,
  360.                                     nElements,
  361.                                     nElements);
  362.  
  363.                 break;
  364.             case kSendData:
  365.                     myATPBPtr = GetOurPBPtr(atpPBPtr);                    
  366.                     bdsPtr = (BDSPtr)myATPBPtr->bdsPtr;
  367.                     
  368.                         /* copy "data" from our resource into our buffer */
  369.                     HLock(gTestDataHdl);
  370.                     BlockMove(*gTestDataHdl,
  371.                                 myATPBPtr->respData,
  372.                                 gTestDataSize);
  373.  
  374.                         /* fill the BDS with our "data" */
  375.                     nElements = BuildBDS(myATPBPtr->respData,
  376.                                         myATPBPtr->bdsPtr,
  377.                                         gTestDataSize);
  378.                     HUnlock(gTestDataHdl);
  379.                     
  380.                     doSendResponse(atpPBPtr,
  381.                                     gOurATPSocket,
  382.                                     (Ptr)bdsPtr,
  383.                                     nElements,
  384.                                     nElements);
  385.                 break;
  386.                 
  387.         }
  388. }
  389.  
  390. // *****************************************************************
  391. // *    doSendResponseIOComp
  392. // *
  393. // *    completion routine for our send response call.
  394. // *****************************************************************
  395. pascal void doSendResponseIOComp(ATPPBPtr atpPBPtr)
  396. {
  397. myATPParamBlockPtr myATPPBPtr;
  398.  
  399.     if (atpPBPtr->ATP.ioResult == noErr)
  400.     {
  401.         myATPPBPtr = GetOurPBPtr(atpPBPtr);
  402.             /* our response was sent, so issue another async. GetRequest
  403.                 so that we may receive another request */
  404.         doGetRequest(atpPBPtr,
  405.                     gOurATPSocket,
  406.                     sizeof(struct ourReqData),
  407.                     myATPPBPtr->reqData);
  408.     }
  409.     else
  410.     {
  411.             /* place parameter block back into the "Done" queue */
  412.         Enqueue((QElemPtr)atpPBPtr,&gDoneQueue);
  413.  
  414.     }
  415. }
  416.  
  417. // *****************************************************************
  418. // *    doSendResponse
  419. // *
  420. // *    We send a response back to the requestor in this routine.
  421. // *****************************************************************
  422. void doSendResponse(ATPPBPtr atpPBPtr,
  423.                     char     socket,
  424.                     Ptr        bdsPtr,
  425.                     char    numOfBuffs,
  426.                     char    bdsSize)
  427. {
  428. OSErr err;
  429.  
  430.     SetOurCompletionRoutine((ProcPtr)&doSendResponseIOComp,
  431.                             atpPBPtr);
  432.  
  433.     atpPBPtr->ATP.atpSocket         = socket;
  434.     atpPBPtr->ATP.atpFlags             = atpEOMvalue + atpSendChkvalue;
  435.     atpPBPtr->ATP.bdsPointer         = bdsPtr;
  436.     atpPBPtr->OTH1.u0.numOfBuffs     = numOfBuffs;        /* num. of resp. bufs being sent */
  437.     atpPBPtr->OTH2.bdsSize             = bdsSize;
  438.         /* note: the "addrBlock" and "transID' fields are already
  439.             set up for us by the just completed GetRequest call */
  440.     err = PSendResponse(atpPBPtr,true);
  441.     if (err != noErr)
  442.     {
  443.         SaveFunctionResultCode(err,
  444.                             atpPBPtr);
  445.     }
  446. }
  447.  
  448.  
  449.  
  450.  
  451. // *****************************************************************
  452. // *    closeOurSocket
  453. // *
  454. // *    close the socket that we used to listen for requests.
  455. // *****************************************************************
  456. void closeOurSocket(char socket)
  457. {
  458. ATPParamBlock pb;
  459.  
  460.     pb.ATP.atpSocket         = socket;
  461.     
  462.     PCloseATPSkt(&pb,false);
  463. }
  464.  
  465.  
  466. // *****************************************************************
  467. // *    CheckDoneQueue
  468. // *
  469. // *    This routine looks through the "Done" queue for calls that
  470. // *    have completed and reports any errors.
  471. // *****************************************************************
  472. void CheckDoneQueue()
  473. {
  474. QElemPtr qElemPtr;
  475. ATPPBPtr atpPBPtr;
  476. myATPParamBlockPtr myATPPBPtr;
  477. OSErr err;
  478.  
  479.  
  480.         /* have any calls completed? */
  481.     if (gDoneQueue.qHead != nil)
  482.     {
  483.         qElemPtr = gDoneQueue.qHead;
  484.         err = Dequeue((QElemPtr)qElemPtr,&gDoneQueue);
  485.         if (err == noErr)
  486.         {
  487.             atpPBPtr = (ATPPBPtr)qElemPtr;
  488.             
  489.                 /* first check function result - was the
  490.                     call queued successfully by the driver? */
  491.             myATPPBPtr = GetOurPBPtr(atpPBPtr);
  492.             if (myATPPBPtr->functionResult != noErr)
  493.             {
  494.                 ShowError(DrvrErr);
  495.             }
  496.                 /* now check ioResult - were there any
  497.                     errors on this particular call? */
  498.             else if (atpPBPtr->ATP.ioResult != noErr)
  499.             {
  500.                 ShowATPError(atpPBPtr);
  501.             }
  502.  
  503.                 /* place queue element back into the "available" queue */
  504.             Enqueue((QElemPtr)qElemPtr,&gAvailQueue);
  505.         }
  506.     }
  507.  
  508. }
  509.  
  510. // *****************************************************************
  511. // *    VerifyData
  512. // *
  513. // *    Verifies that the test data we received matches our own
  514. // *****************************************************************
  515. Boolean VerifyData(myATPParamBlockPtr myATPPbPtr)
  516. {
  517. BDSPtr bds;
  518. Ptr original,received;
  519. Boolean valid;
  520. short i,j;
  521.  
  522.     valid = true;
  523.     bds = (BDSPtr)myATPPbPtr->bdsPtr;
  524.     HLock(gTestDataHdl);
  525.     original = *gTestDataHdl;
  526.     for (i = 0;
  527.         (i < (myATPPbPtr->u.SREQ.numOfResps)) && (valid == true);
  528.         ++i)
  529.     {
  530.         received = bds->buffPtr;
  531.         for (j = 0;
  532.             (j < bds->dataSize) && (valid == true);
  533.             ++j)
  534.         {
  535.             if (*original != *received)
  536.                 valid = false;
  537.             ++original;
  538.             ++received;
  539.         }
  540.         ++bds;    /* next BDS Element */
  541.     }
  542.     HUnlock(gTestDataHdl);
  543.     
  544.     return valid;
  545. }
  546.  
  547.  
  548. // *****************************************************************
  549. // *    CheckRequests
  550. // *
  551. // *****************************************************************
  552. void CheckRequests()
  553. {
  554. QElemPtr qElemPtr;
  555. ATPPBPtr atpPBPtr;
  556. OSErr err;
  557. short reqCode;
  558. myATPParamBlockPtr myATPPBPtr;
  559. Boolean valid;
  560. short nElements;
  561.  
  562.  
  563.         /* have we received any requests? or have any requests that we
  564.             sent completed? */
  565.     if (gRequestQueue.qHead != nil)
  566.     {
  567.         qElemPtr = gRequestQueue.qHead;
  568.         err = Dequeue((QElemPtr)qElemPtr,&gRequestQueue);
  569.         if (err == noErr)
  570.         {
  571.             atpPBPtr = (ATPPBPtr)qElemPtr;
  572.             switch (atpPBPtr->ATP.csCode)
  573.             {
  574.                 case nSendRequest:    /* request that we sent */
  575.                 case sendRequest:
  576.  
  577.                             /* did we request clock time or data? */
  578.                         reqCode = *(atpPBPtr->ATP.reqPointer);
  579.                         switch (reqCode)
  580.                         {
  581.                             case kSendTime:
  582.                                     /* show the clock time */
  583.                                 ShowClockTime(atpPBPtr);
  584.                                 break;
  585.                             case kSendData:
  586.                                 myATPPBPtr = GetOurPBPtr(atpPBPtr);
  587.                                     /* insert your routine here to verify data */
  588.                                 valid = VerifyData(myATPPBPtr);
  589.                                 
  590.                                     /* if "single request" mode is selected,
  591.                                     put up a dialog to report status */
  592.                                 if (gSingleRequest == true)
  593.                                 {
  594.                                     if (valid == true)
  595.                                         ShowError(dataIsValid);
  596.                                     else
  597.                                         ShowError(dataNotValidErr);
  598.                                 }
  599.                                 else    /* "continuous" mode, so print status text in window */
  600.                                 {
  601.                                     if (valid == true)
  602.                                         ShowStatusString(kTestDataCorrect);
  603.                                     else
  604.                                         ShowStatusString(kTestDataIncorrect);
  605.                                 }
  606.                                 break;
  607.                         }
  608.                         
  609.                             /* should we re-issue another request to the target? */
  610.                         if ((gSingleRequest == false) &&
  611.                             (gStopRequests == false))
  612.                         {
  613.                             myATPPBPtr = GetOurPBPtr(atpPBPtr);
  614.                             if (gReqClockTime == true)
  615.                             {
  616.                                 *(myATPPBPtr->reqData) = kSendTime;
  617.                                     /* setup response BDS to hold our
  618.                                         clock/time value */
  619.                                 nElements = BuildBDS(myATPPBPtr->respData,
  620.                                                     myATPPBPtr->bdsPtr,
  621.                                                     4);
  622.                             }
  623.                             else    /* send test "data" */
  624.                             {
  625.                                 *(myATPPBPtr->reqData) = kSendData;
  626.                                 nElements = BuildBDS(myATPPBPtr->respData,
  627.                                                     myATPPBPtr->bdsPtr,
  628.                                                     gTestDataSize);
  629.                             }
  630.                             
  631.                                 /* clear status string first */
  632.                             ShowStatusString(kBlankText);
  633.  
  634.                                 /* send a request to target machine */
  635.                             doSndRequest(atpPBPtr,
  636.                                         gTargetAddress,
  637.                                         gOurATPSocket,
  638.                                         myATPPBPtr->bdsPtr,
  639.                                         2,
  640.                                         myATPPBPtr->reqData,
  641.                                         nElements);
  642.                         }
  643.                         else
  644.                         {
  645.                                 /* place parameter block back into the "Avail" queue */
  646.                             Enqueue((QElemPtr)atpPBPtr,&gAvailQueue);
  647.                         }
  648.                         
  649.                     break;
  650.                     
  651.                 case getRequest:    /* request that we received */
  652.                 
  653.                         /* send back either our machines's clock time
  654.                             or test "data" */
  655.                         SendOurResponseData(atpPBPtr);
  656.                     break;
  657.             }
  658.  
  659.         }
  660.     }
  661.  
  662. }
  663.  
  664. // *****************************************************************
  665. // *    ATPLoop
  666. // *
  667. // *****************************************************************
  668. void ATPLoop()
  669. {
  670.  
  671.     CheckDoneQueue();
  672.     CheckRequests();
  673.  
  674. }
  675.  
  676.  
  677. // *****************************************************************
  678. // *    SendReqToTarget
  679. // *
  680. // *    issues a request to the selected target machine. The target is
  681. // *    selected using the popup menus.
  682. // *****************************************************************
  683. Boolean SendReqToTarget()
  684. {
  685.     MPPParamBlock pbLKP;
  686.     Ptr ntePtr, buffer;
  687.     EntityName abEntity;
  688.     AddrBlock address;
  689.     ATPPBPtr atpPBPtr;
  690.     myATPParamBlockPtr myATPPBPtr;
  691.     Boolean reqSent;
  692.     short nElements;
  693.  
  694.  
  695.         reqSent = false;
  696.         
  697.         ntePtr = nil;
  698.         buffer = nil;
  699.         
  700.         ntePtr = NewPtr(sizeof(NamesTableEntry));
  701.         if (ntePtr == nil)
  702.             goto Done;
  703.  
  704.         buffer = NewPtr(100);
  705.         if (buffer == nil)
  706.             goto Done;
  707.  
  708.         NBPSetEntity(ntePtr, gObjStr, gTypeStr, gZoneString);
  709.         pbLKP.NBP.interval = 3;
  710.         pbLKP.NBP.count = 3;
  711.         pbLKP.NBP.NBPPtrs.entityPtr = ntePtr;
  712.         pbLKP.NBP.parm.Lookup.retBuffSize = 100;
  713.         pbLKP.NBP.parm.Lookup.retBuffPtr = buffer;
  714.         pbLKP.NBP.parm.Lookup.maxToGet = 1;
  715.  
  716.             /* first let's try and locate the selected machine on the network */
  717.         if (PLookupName(&pbLKP, false) == noErr)
  718.         {        /* did we find it? */
  719.             if ( pbLKP.NBP.parm.Lookup.numGotten > 0)
  720.             {        /* go ahead and send a request to the target */
  721.                 if (NBPExtract(buffer, pbLKP.NBP.parm.Lookup.numGotten, 1, &abEntity, &address) == noErr)
  722.                 {
  723.                         /* save the target address */
  724.                     gTargetAddress = address;
  725.                     
  726.                     atpPBPtr = GetQElement(&gAvailQueue);
  727.                     if (atpPBPtr != NULL)
  728.                     {
  729.                         myATPPBPtr = GetOurPBPtr(atpPBPtr);
  730.                             /* sending clock time or "data" ? */
  731.                         if (gReqClockTime == true)
  732.                         {
  733.                             *(myATPPBPtr->reqData) = kSendTime;
  734.                                 /* setup response BDS to hold our
  735.                                     clock/time value */
  736.                             nElements = BuildBDS(myATPPBPtr->respData,
  737.                                                 myATPPBPtr->bdsPtr,
  738.                                                 4);
  739.                         }
  740.                         else    /* send test "data" */
  741.                         {
  742.                             *(myATPPBPtr->reqData) = kSendData;
  743.                             nElements = BuildBDS(myATPPBPtr->respData,
  744.                                                 myATPPBPtr->bdsPtr,
  745.                                                 gTestDataSize);
  746.                         }
  747.                         
  748.                             /* send a request to target machine */
  749.                         doSndRequest(atpPBPtr,
  750.                                     address,
  751.                                     gOurATPSocket,
  752.                                     myATPPBPtr->bdsPtr,
  753.                                     2,
  754.                                     myATPPBPtr->reqData,
  755.                                     nElements);
  756.                                     
  757.                         reqSent = true;
  758.                     }
  759.                 }
  760.                         
  761.             }
  762.             else    /* target not found */
  763.             {
  764.                 ShowError(noTargetErr);
  765.                     /* re-enable send request button */
  766.                 HiliteSendReqButton (0);
  767.             }
  768.         }
  769.         
  770.         Done:
  771.         
  772.         if (ntePtr != nil)
  773.             DisposPtr(ntePtr);
  774.         if (buffer != nil)
  775.             DisposPtr(buffer);
  776.         
  777.         return reqSent;
  778. }
  779.  
  780. // *****************************************************************
  781. // *    initializeATP
  782. // *
  783. // *    allocates parameter blocks for our atp calls, opens a socket
  784. // *    for us to receive requests on, registers our name on the network.
  785. // *****************************************************************
  786. void initializeATP()
  787. {
  788.     InitQueues();
  789.  
  790.     if (GetASocket(&gOurATPSocket) == true)
  791.         registerMyName(gOurATPSocket);
  792.     else
  793.         FatalError(SktErr);
  794.  
  795. }
  796.  
  797. // *****************************************************************
  798. // *    removeATP
  799. // *
  800. // *    removes our nbp name from the network, closes our atp socket
  801. // *    and de-allocates the memory we used for our parameter blocks.
  802. // *****************************************************************
  803. void removeATP()
  804. {
  805.     closeOurSocket(gOurATPSocket);
  806.     removeMyName();
  807. }
  808.  
  809.  
  810. // *****************************************************************
  811. // *    GetClockTime
  812. // *
  813. // *****************************************************************
  814. void GetClockTime(Ptr buf)
  815. {
  816.     unsigned long secs;
  817.  
  818.         GetDateTime(&secs);
  819.         BlockMove(&secs, buf, 4);
  820. }
  821.  
  822. // *****************************************************************
  823. // *    ShowStatusString
  824. // *
  825. // *****************************************************************
  826. void ShowStatusString(StringPtr str)
  827. {
  828.     Rect r;
  829.     short kind;
  830.     Handle h;
  831.  
  832.  
  833.         GetDItem(myDialog, kStatusText, &kind, &h, &r);
  834.         SetIText(h, str);
  835.  
  836. }
  837.  
  838. // *****************************************************************
  839. // *    ShowClockTime
  840. // *
  841. // *****************************************************************
  842. void ShowClockTime(ATPPBPtr atpPBPtr)
  843. {
  844.     Rect r;
  845.     short kind;
  846.     Handle h;
  847.     Str255 str,str2;
  848.     BDSPtr bdsPtr;
  849.     long dateTime;
  850.  
  851.  
  852.         GetDItem(myDialog, kClockTime, &kind, &h, &r);
  853.         GetIText(h, str2);
  854.         
  855.         bdsPtr = (BDSPtr)atpPBPtr->ATP.bdsPointer;
  856.         BlockMove(bdsPtr->buffPtr, &dateTime, 4);
  857.         IUTimeString(dateTime, true, str);
  858.             /* this just checks to see that we're not already displaying this time already */
  859.             /* flashing text sucks... so sayeth me */
  860.         if (IUCompString(str,str2) != 0)
  861.             SetIText(h, &str);
  862.  
  863. }
  864.  
  865.  
  866. // *****************************************************************
  867. // *    SetUpATPError
  868. // *
  869. // *    sets our error string for the desired error code
  870. // *****************************************************************
  871. void SetUpATPError(OSErr err,
  872.                     StringPtr displayStr)
  873. {
  874.     switch (err)
  875.     {
  876.         case reqFailed:
  877.             PStrCat("\pSend Request failed. Retry count exceeded.",(Ptr)displayStr);
  878.           break;
  879.           
  880.         case tooManyReqs:
  881.             PStrCat("\pToo many concurrent requests.",(Ptr)displayStr);
  882.           break;
  883.  
  884.         case noDataArea:
  885.             PStrCat("\pToo many outstanding ATP calls.",(Ptr)displayStr);
  886.           break;
  887.           
  888.         case badATPSkt:
  889.             PStrCat("\pBad responding socket.",(Ptr)displayStr);
  890.           break;
  891.  
  892.         case noRelErr:
  893.             PStrCat("\pNo release received.",(Ptr)displayStr);
  894.           break;
  895.  
  896.         case badBuffNum:
  897.             PStrCat("\pBad sequence number.",(Ptr)displayStr);
  898.           break;
  899.  
  900.         case sktClosedErr:
  901.             PStrCat("\pAsynchronous call aborted because socket was closed.",(Ptr)displayStr);
  902.           break;
  903.           
  904.         default:
  905.             NumToString(err,(Ptr)displayStr);
  906.         
  907.     }
  908.  
  909. }
  910.  
  911. // *****************************************************************
  912. // *    ShowATPError
  913. // *
  914. // *    If one of our asynchronous atp calls returned an error, the
  915. // *    parameter block gets stuffed into an error OSQueue by the completion
  916. // *    routine. This error queue is checked periodically by this routine.
  917. // *    If the queue is not empty, then we got an error so we display it here
  918. // *    and do any processing of the error that we want.
  919. // *****************************************************************
  920. void ShowATPError(ATPPBPtr atpPBPtr)
  921. {
  922.     Rect r;
  923.     short kind;
  924.     Handle h;
  925.     short itemHit;
  926.     Str255 displayStr,theError;
  927.     
  928.  
  929.             displayStr[0] = 0;
  930.             
  931.                 /*  Use cscode field of the parameter block
  932.                    to see which call this error is for*/
  933.             switch (atpPBPtr->ATP.csCode)
  934.             {
  935.                 case getRequest:
  936.                         /* dont report errors if we cancel the call */
  937.                     if (atpPBPtr->ATP.ioResult != reqAborted)
  938.                     {
  939.                         CopyPstr("\pGetRequest error. ",&displayStr);
  940.                         SetUpATPError(atpPBPtr->ATP.ioResult, &displayStr);
  941.                     }
  942.                  break;
  943.     
  944.                 case nSendRequest:
  945.                     CopyPstr("\pSendRequest error. ",&displayStr);
  946.                     SetUpATPError(atpPBPtr->ATP.ioResult, &displayStr);
  947.                     
  948.                     /* we got an error so stop sending requests if we are in
  949.                         "continuous" mode */
  950.                     if (gDoContinuous == true)
  951.                     {
  952.                         GetDItem(myDialog, kReqDataButton, &kind, &h, &r);
  953.                         SetCTitle((ControlHandle)h, "\pRequest Data");
  954.                     }
  955.                  break;
  956.             
  957.                 case sendResponse:
  958.                     CopyPstr("\pSendResponse error. ",&displayStr);
  959.                     SetUpATPError(atpPBPtr->ATP.ioResult, &displayStr);
  960.                  break;
  961.  
  962.                 default:
  963.                     CopyPstr("\pError: ",&displayStr);
  964.                     NumToString(atpPBPtr->ATP.ioResult,theError);
  965.                     PStrCat(theError,(Ptr)displayStr);
  966.                 break;
  967.     
  968.             }
  969.  
  970.                 /* if we have a message we want to show, put up a dialog
  971.                     for the user */
  972.             if (displayStr[0] != 0)
  973.             {
  974.                 ParamText(displayStr,"\p","\p","\p");
  975.                 itemHit = Alert(rErrorDialog, nil);
  976.             }
  977.         
  978.             /* re-enable send request button */
  979.             HiliteSendReqButton (0);
  980.         
  981. }